using AgentFrameworkDemo.Services;
using Microsoft.Extensions.Logging;
using System.ComponentModel;

namespace AgentFrameworkDemo.Plugins;

/// <summary>
/// Agent记忆插件
/// </summary>
public class AgentMemoryPlugin
{
    private readonly IMemoryManager _memoryManager;
    private readonly ILogger<AgentMemoryPlugin> _logger;
    private readonly string _agentId;

    public AgentMemoryPlugin(IMemoryManager memoryManager, ILogger<AgentMemoryPlugin> logger, string agentId)
    {
        _memoryManager = memoryManager;
        _logger = logger;
        _agentId = agentId;
    }

    [Description("搜索记忆中的信息")]
    public async Task<string> SearchMemoryAsync(string query)
    {
        try
        {
            var memories = await _memoryManager.SearchMemoriesAsync(_agentId, query, 5);
            if (!memories.Any())
            {
                return "未找到相关信息。";
            }

            var result = "找到以下相关信息：\n";
            foreach (var memory in memories)
            {
                result += $"- {memory.Content} (时间: {memory.CreatedAt:yyyy-MM-dd HH:mm:ss})\n";
            }

            return result;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to search memory for agent: {AgentId}", _agentId);
            return $"搜索记忆时出错: {ex.Message}";
        }
    }

    [Description("获取最近的记忆")]
    public async Task<string> GetRecentMemoriesAsync()
    {
        try
        {
            var memories = await _memoryManager.GetMemoriesAsync(_agentId, 10);
            if (!memories.Any())
            {
                return "暂无记忆信息。";
            }

            var result = "最近的记忆：\n";
            foreach (var memory in memories)
            {
                result += $"- {memory.Content} (时间: {memory.CreatedAt:yyyy-MM-dd HH:mm:ss})\n";
            }

            return result;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get recent memories for agent: {AgentId}", _agentId);
            return $"获取记忆时出错: {ex.Message}";
        }
    }
}

/// <summary>
/// 日期时间工具插件
/// </summary>
public class DateTimeToolPlugin
{
    private readonly ILogger<DateTimeToolPlugin> _logger;

    public DateTimeToolPlugin(ILogger<DateTimeToolPlugin> logger)
    {
        _logger = logger;
    }

        [Description("获取当前日期和时间")]
    public string GetCurrentDateTime()
    {
        var now = DateTime.UtcNow;
        return $"当前时间: {now:yyyy-MM-dd HH:mm:ss} UTC\n本地时间: {now.ToLocalTime():yyyy-MM-dd HH:mm:ss}\n时间戳: {((DateTimeOffset)now).ToUnixTimeSeconds()}";
    }

        [Description("获取当前日期")]
    public string GetCurrentDate()
    {
        return DateTime.UtcNow.ToString("yyyy-MM-dd");
    }

        [Description("获取当前时间")]
    public string GetCurrentTime()
    {
        return DateTime.UtcNow.ToString("HH:mm:ss");
    }

        [Description("获取星期几")]
    public string GetDayOfWeek()
    {
        return DateTime.UtcNow.DayOfWeek.ToString();
    }

        [Description("格式化日期时间")]
    public string FormatDateTime(string format = "yyyy-MM-dd HH:mm:ss")
    {
        try
        {
            return DateTime.UtcNow.ToString(format);
        }
        catch
        {
            return "格式错误，请使用有效的日期格式。";
        }
    }
}

/// <summary>
/// 文本处理工具插件
/// </summary>
public class TextToolPlugin
{
    private readonly ILogger<TextToolPlugin> _logger;

    public TextToolPlugin(ILogger<TextToolPlugin> logger)
    {
        _logger = logger;
    }

        [Description("计算文本长度")]
    public int GetTextLength(string text)
    {
        return text?.Length ?? 0;
    }

        [Description("将文本转换为大写")]
    public string ToUpperCase(string text)
    {
        return text?.ToUpper() ?? string.Empty;
    }

        [Description("将文本转换为小写")]
    public string ToLowerCase(string text)
    {
        return text?.ToLower() ?? string.Empty;
    }

        [Description("反转文本")]
    public string ReverseText(string text)
    {
        return string.IsNullOrEmpty(text) ? string.Empty : new string(text.Reverse().ToArray());
    }

        [Description("去除文本首尾空白字符")]
    public string TrimText(string text)
    {
        return text?.Trim() ?? string.Empty;
    }

        [Description("检查文本是否包含指定内容")]
    public bool ContainsText(string text, string search)
    {
        return !string.IsNullOrEmpty(text) && text.Contains(search, StringComparison.OrdinalIgnoreCase);
    }

        [Description("替换文本中的内容")]
    public string ReplaceText(string text, string oldValue, string newValue)
    {
        return text?.Replace(oldValue, newValue) ?? string.Empty;
    }
}

/// <summary>
/// 数学计算工具插件
/// </summary>
public class MathToolPlugin
{
    private readonly ILogger<MathToolPlugin> _logger;

    public MathToolPlugin(ILogger<MathToolPlugin> logger)
    {
        _logger = logger;
    }

        [Description("执行加法运算")]
    public double Add(double a, double b)
    {
        return a + b;
    }

        [Description("执行减法运算")]
    public double Subtract(double a, double b)
    {
        return a - b;
    }

        [Description("执行乘法运算")]
    public double Multiply(double a, double b)
    {
        return a * b;
    }

        [Description("执行除法运算")]
    public double Divide(double a, double b)
    {
        if (b == 0)
            throw new DivideByZeroException("除数不能为零");
        return a / b;
    }

        [Description("计算幂运算")]
    public double Power(double baseNumber, double exponent)
    {
        return Math.Pow(baseNumber, exponent);
    }

        [Description("计算平方根")]
    public double SquareRoot(double number)
    {
        if (number < 0)
            throw new ArgumentException("不能计算负数的平方根");
        return Math.Sqrt(number);
    }

        [Description("计算绝对值")]
    public double AbsoluteValue(double number)
    {
        return Math.Abs(number);
    }

        [Description("四舍五入到指定小数位")]
    public double Round(double number, int decimals = 2)
    {
        return Math.Round(number, decimals);
    }

        [Description("计算阶乘")]
    public double Factorial(int n)
    {
        if (n < 0)
            throw new ArgumentException("不能计算负数的阶乘");
        if (n > 170) // 防止溢出
            throw new ArgumentException("数值过大，可能导致溢出");

        double result = 1;
        for (int i = 2; i <= n; i++)
        {
            result *= i;
        }
        return result;
    }
}

/// <summary>
/// 天气查询工具插件（模拟）
/// </summary>
public class WeatherToolPlugin
{
    private readonly ILogger<WeatherToolPlugin> _logger;
    private readonly Random _random = new();

    public WeatherToolPlugin(ILogger<WeatherToolPlugin> logger)
    {
        _logger = logger;
    }

        [Description("查询指定城市的天气信息")]
    public string GetWeather(string city)
    {
        if (string.IsNullOrWhiteSpace(city))
        {
            return "请提供有效的城市名称。";
        }

        // 模拟天气数据
        var weatherConditions = new[] { "晴天", "多云", "阴天", "小雨", "中雨", "雷阵雨", "小雪", "中雪" };
        var condition = weatherConditions[_random.Next(weatherConditions.Length)];

        var temperature = _random.Next(-10, 35);
        var humidity = _random.Next(30, 90);
        var windSpeed = _random.Next(0, 30);
        var pressure = _random.Next(990, 1030);

        return $"📍 {city}当前天气情况：\n" +
               $"🌤 天气：{condition}\n" +
               $"🌡️ 温度：{temperature}°C\n" +
               $"💧 湿度：{humidity}%\n" +
               $"💨 风速：{windSpeed} km/h\n" +
               $"🔽 气压：{pressure} hPa\n" +
               $"📅 更新时间：{DateTime.Now:yyyy-MM-dd HH:mm:ss}\n\n" +
               $"⚠️ 注意：这是模拟数据，实际天气请查看专业天气应用。";
    }

        [Description("查询城市天气预报（模拟）")]
    public string GetWeatherForecast(string city, int days = 3)
    {
        if (string.IsNullOrWhiteSpace(city))
        {
            return "请提供有效的城市名称。";
        }

        if (days < 1 || days > 7)
        {
            return "天气预报天数应在1-7天之间。";
        }

        var forecast = $"📍 {city}未来{days}天天气预报：\n\n";

        for (int i = 1; i <= days; i++)
        {
            var futureDate = DateTime.Now.AddDays(i);
            var weatherConditions = new[] { "晴天", "多云", "阴天", "小雨", "中雨" };
            var condition = weatherConditions[_random.Next(weatherConditions.Length)];
            var highTemp = _random.Next(15, 30);
            var lowTemp = _random.Next(-5, 20);

            forecast += $"📅 第{i}天 ({futureDate:MM月dd日}): {condition}\n";
            forecast += $"   🌡️ 气温：{lowTemp}°C ~ {highTemp}°C\n\n";
        }

        forecast += "⚠️ 注意：这是模拟预报，实际天气请查看专业气象服务。";
        return forecast;
    }
}